package com.leha.mp.core.services.imp;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.leha.mp.core.Utils.Page;
import com.leha.mp.core.Utils.TimeIndexHelper;
import com.leha.mp.core.config.NoticeMessageConfig;
import com.leha.mp.core.constants.BizConstants;
import com.leha.mp.core.constants.CoreErrorDict;
import com.leha.mp.core.dao.*;
import com.leha.mp.core.entity.mybatis.*;
import com.leha.mp.core.entity.templateMsg.CaseReviewResultMsg;
import com.leha.mp.core.entity.templateMsg.ConsultingAcceptedMsg;
import com.leha.mp.core.entity.templateMsg.ConsultingCancleMsg;
import com.leha.mp.core.entity.vo.*;
import com.leha.mp.core.services.*;
import com.leha.utils.DateTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Predicate;

@Service
public class AppDoctorServicesImpl implements AppDoctorServices {
    @Autowired
    CustomLogicMapper customLogicMapper;
    @Autowired
    PlOrderMapper orderMapper;
    @Autowired
    PlProductMapper doctorProductMapper;
    @Autowired
    PlUserVipMapper userVipMapper;
    @Autowired
    ConfluenceServices confluenceServices;
    @Autowired
    PlDoctorAvailableTimeMapper availableTimeMapper;
    @Autowired
    PlDoctorScheduleMapper scheduleMapper;
    @Autowired
    PlConsultingMapper consultingMapper;
    @Autowired
    WAppServices appServices;
    @Autowired
    PlUserMapper userMapper;
    @Autowired
    QaDoctorMapper doctorMapper;
    @Autowired
    PlCaseMapper caseMapper;
    @Autowired
    PlVipMapper vipRecordMapper;
    @Autowired
    ConfluenceServices bizSrvs;
    @Autowired
    OrderServices orderServices;
    @Autowired
    PlDockerUserRelationMapper relationMapper;
    @Autowired
    MpDoctorCodeMapper doctorCodeMapper;
    @Autowired
    PushServices pushServices;
    @Autowired
    BedgeServices bedgeServices;
    @Autowired
    BalanceServices balanceServices;
    @Autowired
    WxMPQrCodeServices codeServices;
    @Autowired
    AppDoctorServices doctorServices;

    @Autowired
    ErrorMessageServices errorMessageServices;

    @Autowired
    CommonServicesImpl commonServices;

    private static final Logger LOG = LoggerFactory.getLogger(AppDoctorServicesImpl.class);

    @Override
    public DoctorLoginVO saveInfo(Integer appId, Integer uid, String sessionKey, String encryptedData, String iv) {
        try {
            //PlUser user = userMapper.selectByPrimaryKey(uid);
            PlUser user = new PlUser();
            user.setUid(uid);
            WxMaService wxService = appServices.getAppMAServices(appId);
            WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
            user.setAvatarUrl(userInfo.getAvatarUrl());
            user.setNickname(userInfo.getNickName());
            user.setChannel(appId);
            //LOG.info("unionId:",user.getUnionid());
            userMapper.updateByPrimaryKeySelective(user);
            return new DoctorLoginVO(user);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            errorMessageServices.setError(CoreErrorDict.WXQRCodeRequsetFaild);
            return null;
        }
    }

    private DoctorLoginVO fillDoctorInfo(PlUser u, String sessionKey) {
        QaDoctorExample ex = new QaDoctorExample();
        ex.createCriteria().andUserIdEqualTo(u.getUid());
        List<QaDoctor> r = doctorMapper.selectByExample(ex);
        if(r.size()>0) {
            List<DoctorScheduleVo> sche = getDoctorSchedule(r.get(0).getId(),
                    DateTool.getNowTime("yyyy-MM-dd"),
                    DateTool.formatDate(DateTool.DayOp(new Date(), 6), "yyyy-MM-dd"));
            PlProductExample pex = new PlProductExample();
            pex.createCriteria().andDoctorIdEqualTo(r.get(0).getId()).andStatusEqualTo(0);
            List<PlProduct> products = doctorProductMapper.selectByExample(pex);
            DoctorRichInfoVo base = customLogicMapper.getDoctorRichInfo(r.get(0).getId());

            MpDoctorCode code = doctorCodeMapper.selectByPrimaryKey(base.getId());
            if(code==null) {
                code = codeServices.generateDoctorCode(base.getId());
            }
            DoctorLoginVO v = new DoctorLoginVO(u, sessionKey, base.toBaseInfo(), sche, products);
            v.setQrCode("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+code.getTicket());
            return v;
        }
        return new DoctorLoginVO(u, sessionKey, null, null, null);
    }

    @Override
    public DoctorLoginVO enter(Integer appId, String code) {
        try {
            WxMaService wxService = appServices.getAppMAServices(appId);
            if(wxService==null) {
                errorMessageServices.setError(CoreErrorDict.RESULT_ERROR);
                return null;
            }
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            LOG.info(session.getSessionKey());
            LOG.info(session.getOpenid());
            PlUserExample ex = new PlUserExample();
            ex.createCriteria().andOpenidEqualTo(session.getOpenid());
            List<PlUser> user = userMapper.selectByExample(ex);
            if(user.size()==0) {
                PlUser newUser = new PlUser();
                newUser.setOpenid(session.getOpenid());
                newUser.setChannel(appId);
                newUser.setUnionid(session.getUnionid());
                LOG.info("unionId:",session.getUnionid());
                userMapper.insertSelective(newUser);
                return fillDoctorInfo(newUser, session.getSessionKey());
            } else {
                LOG.info("existUser:",session.getUnionid());
                PlUser u = user.get(0);
                if(u.getUnionid()==null || u.getUnionid().isEmpty()) {
                    u.setUnionid(session.getUnionid());
                    userMapper.updateByPrimaryKeySelective(u);
                }
                return fillDoctorInfo(u, session.getSessionKey());
            }
        } catch (Exception e) {
            e.printStackTrace();
            errorMessageServices.setError(CoreErrorDict.WXError);
            return null;
        }
    }

    @Override
    public DoctorRichInfoVo getDoctorRichInfo(Integer did, Integer uid) {
        DoctorRichInfoVo rich = customLogicMapper.getDoctorRichInfo(did);
        if(rich==null) {
            return null;
        }
        PlProductExample ex = new PlProductExample();
        ex.createCriteria().andDoctorIdEqualTo(did).andStatusEqualTo(0);
        rich.setDoctorProduct(doctorProductMapper.selectByExample(ex));
        if(uid != 0) {
            PlUserVipKey key = new PlUserVipKey();
            key.setDoctorId(did);
            key.setUserId(uid);
            PlUserVip vip = userVipMapper.selectByPrimaryKey(key);
            if(vip != null) {
                rich.setMsgTimes(vip.getMsgTimesLeft());
                rich.setVideoTimes(vip.getVideoTimesLeft());
                rich.setPhoneTimes(vip.getPhoneTimesLeft());
                rich.setVipExpireTime(vip.getExpiredTime());
                rich.setIsVip(vip.getExpiredTime().getTime()>new Date().getTime());
            }
        }
        return rich;
    }

    @Override
    public DoctorBaseInfoVo getDoctorBaseInfo(Integer did) {
       return customLogicMapper.getDoctorRichInfo(did).toBaseInfo();
    }

    @Override
    public void updateDoctorStatics(Integer doctorId) {
        Integer memCnt = customLogicMapper.getDoctorSrvMembers(doctorId);
        Integer totalCnt = customLogicMapper.getDoctorSrvNums(doctorId);
        customLogicMapper.updateDoctorSrvCnt(doctorId, memCnt, totalCnt);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelConsulting(Integer doctorId, Integer consultingId) {
        PlConsulting consulting = consultingMapper.selectByPrimaryKey(consultingId);
        if( ! consulting.getDoctorId().equals(doctorId) || consulting.getStatus()!=BizConstants.Consulting_Status_Accepted
                || consulting.getConsultingType()==BizConstants.Consulting_Type_Msg) {
            errorMessageServices.setError(CoreErrorDict.ConsultStatusError);
            return false;
        }

        if ( commonServices.refundMoneyForConsult(consulting, BizConstants.Consulting_Status_Reject) ) {
            //pushServices.SendMessageToUserWithMp(consulting.getUserId(), NoticeMessageConfig.getConsultingExpiredMessage());
            DoctorBaseInfoVo v = doctorServices.getDoctorBaseInfo(consulting.getDoctorId());
            String fee = "私人医生无费用，相应次数已退还";
            if(consulting.getOrderId()!=0) {
                PlOrder order = orderMapper.selectByPrimaryKey(consulting.getOrderId());
                fee = new Double(order.getOrderFee().doubleValue()/100.0).toString()+"元";
            }
            ConsultingCancleMsg msg = ConsultingCancleMsg.msgBuilder(v.getHospital(), v.getName(), fee);
            pushServices.SendMessageToUserWithMp(consulting.getUserId(), JSON.toJSONString(msg));
        } else {
            errorMessageServices.setError(CoreErrorDict.ERROR_CONSULTING_REFUND_FAIL);
            return false;
        }

        try {
            JSONObject obj = JSON.parseObject(consulting.getExtraData());
            //清理日程安排
            PlDoctorScheduleKey sche = new PlDoctorScheduleKey();
            String sd = obj.getString(BizConstants.Consulting_Str_ScheduleDate_Key);
            String index = obj.getString(BizConstants.Consulting_Str_ScheduleTimeIndex_Key);

            if (sd == null || index == null) {
                errorMessageServices.setError(CoreErrorDict.ConsultExtraDataError);
                return false;
            }
            sche.setDateindex(index);
            sche.setScheduleDate(DateTool.strToDate(sd));
            sche.setDoctorId(doctorId);
            scheduleMapper.deleteByPrimaryKey(sche);

            return consultingMapper.updateByPrimaryKeySelective(consulting) > 0;
        } catch (Exception e) {
            errorMessageServices.setError(CoreErrorDict.SYSTEM_ERROR);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PlConsulting genVipConsulting(Integer userId, Integer productId, Integer doctorId , String extraData) {
        PlUserVipKey key = new PlUserVipKey();
        key.setDoctorId(doctorId);
        key.setUserId(userId);
        PlUserVip vip = userVipMapper.selectByPrimaryKey(key);
        if(vip == null) {
            errorMessageServices.setError(CoreErrorDict.No_VIP_INFO);
            return null;
        }
        PlProduct product = doctorProductMapper.selectByPrimaryKey(productId);
        if(product==null) {
            errorMessageServices.setError(CoreErrorDict.WRONG_DATA);
            return null;
        }
        if(checkVips(vip, product)) {
            PlConsulting consulting = confluenceServices.genConsulting(userId, 0, product, extraData, true);
            if(consulting!=null) {
                updateVips(vip, product);
                updateDoctorStatics(doctorId);
            } else {
                errorMessageServices.setError(CoreErrorDict.ArrangeTimeInvalide);
            }
            return consulting;
        } else {
            errorMessageServices.setError(CoreErrorDict.NoTimesLeft);
            return null;
        }
    }

    @Override
    public DoctorSrvTimeVo getDoctorSrvTimes(Integer doctorId) {
        PlDoctorAvailableTimeExample ex = new PlDoctorAvailableTimeExample();
        ex.createCriteria().andDoctorIdEqualTo(doctorId);
        List<PlDoctorAvailableTime> dav = availableTimeMapper.selectByExample(ex);
        HashMap<String , ArrayList> timeAvailbale = new HashMap<>();
        Date now = new Date();
        //拼装医生可用时间
        for(int i=0;i<7;i++) {
            Date curDate = DateTool.DayOp(now, i);
            String curDateStr = DateTool.formatDate(curDate, "yyyy-MM-dd");
            int weekIndex = DateTool.getDAY_OF_WEEK(curDate);
            for(PlDoctorAvailableTime at:dav) {
                if(at.getTimeIndex()==weekIndex) {
                    ArrayList<String>  timeIndexs = new ArrayList<String>(Arrays.asList(at.getTimeValue().split(",")));
                    //今天的时间要过滤掉已经过去的时间
                    if(i==0) {
                        Integer index = TimeIndexHelper.getCurrentTimeIndex();
                        Predicate<String> predicate = (s) -> Integer.valueOf(s)<= index;
                        timeIndexs.removeIf(predicate);
                    }
                    timeAvailbale.put(curDateStr, timeIndexs);
                    break;
                }
            }
        }
        PlDoctorScheduleExample pse = new PlDoctorScheduleExample();
        pse.createCriteria().andDoctorIdEqualTo(doctorId).andScheduleDateBetween(DateTool.DayOp(now, -1), DateTool.DayOp(now, 6));
        List<PlDoctorSchedule> ps = scheduleMapper.selectByExample(pse);
        for(PlDoctorSchedule pst: ps) {
            String curDateStr = DateTool.formatDate(pst.getScheduleDate(), "yyy-MM-dd");
            if(timeAvailbale.containsKey(curDateStr)) {
                ArrayList arrange = timeAvailbale.get(curDateStr);
                Predicate<String> predicate = (s) -> s.equals(pst.getDateindex());
                arrange.removeIf(predicate);
                timeAvailbale.put(curDateStr, arrange);
            }
        }
        HashMap<String, String> ret = new HashMap<>();
        for (String key : timeAvailbale.keySet()) {
            ret.put(key, String.join(",", timeAvailbale.get(key)));
        }
        DoctorSrvTimeVo resvo = new DoctorSrvTimeVo();
        resvo.setDoctorId(doctorId);
        resvo.setArrange(ret);
        return resvo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean acceptConsulting(Integer doctorId, Integer consultId) {
        PlConsulting consulting = consultingMapper.selectByPrimaryKey(consultId);
        if(! consulting.getDoctorId().equals(doctorId) || consulting.getStatus()!=BizConstants.Consulting_Status_Payed
                || consulting.getConsultingType()==BizConstants.Consulting_Type_Msg) {
            errorMessageServices.setError(CoreErrorDict.ConsultStatusError);
            return false;
        }
        try {
            JSONObject obj = JSON.parseObject(consulting.getExtraData());
            PlDoctorSchedule sche = new PlDoctorSchedule();
            String sd = obj.getString(BizConstants.Consulting_Str_ScheduleDate_Key);
            String index = obj.getString(BizConstants.Consulting_Str_ScheduleTimeIndex_Key);
            String st = obj.getString(BizConstants.Consulting_Str_ScheduleTimeStr_Key);

            if (sd == null || index == null) {
                errorMessageServices.setError(CoreErrorDict.ConsultExtraDataError);
                return false;
            }
            sche.setConsultingId(consultId);
            sche.setUserId(consulting.getUserId());
            sche.setDateindex(index);
            sche.setScheduleDate(DateTool.strToDate(sd));
            sche.setDoctorId(doctorId);
            //已有日程
            PlDoctorSchedule ext = scheduleMapper.selectByPrimaryKey(sche);
            if(ext != null) {
                errorMessageServices.setError(CoreErrorDict.Duplicate_Schedule_Arranged);
                return false;
            }
            consulting.setStatus(BizConstants.Consulting_Status_Accepted);
            consultingMapper.updateByPrimaryKeySelective(consulting);
            DoctorBaseInfoVo ui = doctorServices.getDoctorBaseInfo(consulting.getDoctorId());
            ConsultingAcceptedMsg msg = ConsultingAcceptedMsg.msgBuilder(
                ui.getName(),
                sd+" "+st,
                    consultId.toString()
            );
            pushServices.SendMessageToUserWithMp(consulting.getUserId(), JSON.toJSONString(msg));
            bedgeServices.UpdateUserBedge(consulting.getUserId(),BedgeServices.Type_User_My_Arrange, consultId, 1);
            return scheduleMapper.insertSelective(sche) > 0;
        } catch (Exception e) {
            errorMessageServices.setError(CoreErrorDict.Duplicate_Schedule);
            return false;
        }
    }

    @Override
    public List<DoctorScheduleVo> getDoctorSchedule(Integer doctorId, String beginTime, String endTime) {
        List<UserCaseVo> userCaseVos = customLogicMapper.getDoctorScheduleCase(doctorId, beginTime, endTime);
        HashMap<String, List> tmpCase = new HashMap<>();
        for(UserCaseVo userCase:userCaseVos) {
            if(!tmpCase.containsKey(userCase.getSd())) {
                tmpCase.put(userCase.getSd(), new ArrayList<UserCaseVo>());
            }
            tmpCase.get(userCase.getSd()).add(userCase);
        }
        List<DoctorScheduleVo> ret = new ArrayList<>();
        for(String key:tmpCase.keySet()) {
            DoctorScheduleVo v = new DoctorScheduleVo();
            v.setScheduteDate(key);
            v.setUserConsulting(tmpCase.get(key));
            ret.add(v);
        }
        return ret;
    }

    @Override
    public List<UserCaseVo> getMyConsulting(Integer doctorId, Integer type, Page page) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        return customLogicMapper.getDoctorConsulting(doctorId, type);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rejectConsulting(Integer doctorId, Integer consultingId) {
        PlConsulting consulting = consultingMapper.selectByPrimaryKey(consultingId);
        if(! consulting.getDoctorId().equals(doctorId) || consulting.getStatus()!=BizConstants.Consulting_Status_Payed
                || consulting.getConsultingType()==BizConstants.Consulting_Type_Msg) {
            errorMessageServices.setError(CoreErrorDict.ConsultStatusError);
            return false;
        }

        if ( commonServices.refundMoneyForConsult(consulting, BizConstants.Consulting_Status_Reject) ) {
            pushServices.SendMessageToUserWithMp(consulting.getUserId(), NoticeMessageConfig.getConsultingExpiredMessage());
        } else {
            errorMessageServices.setError(CoreErrorDict.ERROR_CONSULTING_REFUND_FAIL);
            return false;
        }

        return true;
    }

    @Override
    public void refundVips(Integer userId, Integer doctorId, Byte consultingType) {
        PlUserVipKey key = new PlUserVipKey();
        key.setDoctorId(doctorId);
        key.setUserId(userId);
        PlUserVip u = userVipMapper.selectByPrimaryKey(key);
        if(consultingType.equals(BizConstants.Consulting_Type_Msg)) {
            u.setMsgTimesLeft(u.getMsgTimesLeft()+1);
        } else if(consultingType.equals(BizConstants.Consulting_Type_Video)) {
            u.setVideoTimesLeft(u.getVideoTimesLeft()+1);
        } else if(consultingType.equals(BizConstants.Consulting_Type_Phone)) {
            u.setPhoneTimesLeft(u.getPhoneTimesLeft()+1);
        }
        userVipMapper.updateByPrimaryKeySelective(u);
    }

    @Override
    public List<PatientVo> getMyPatients(Integer doctorId) {
        return customLogicMapper.getMyPatientVo(doctorId, BizConstants.CaseStats_Accept);
    }

    @Override
    public Boolean updateDoctorServis(Integer doctorId, Integer type, Integer op) {
        PlProductExample ex = new PlProductExample();
        ex.createCriteria().andTypeEqualTo(type).andDoctorIdEqualTo(doctorId);
        List<PlProduct> res = doctorProductMapper.selectByExample(ex);
        if(res.size()>0) {
            if(op.equals(BizConstants.Srv_Op_Disable)) {
                for(PlProduct product:res) {
                    if(product.getStatus().equals(BizConstants.Data_Status_Normal)) {
                        product.setStatus(BizConstants.Data_Status_Delete);
                        doctorProductMapper.updateByPrimaryKeySelective(product);
                    }
                }
            } else {
                for(PlProduct product:res) {
                    if(product.getStatus().equals(BizConstants.Data_Status_Delete)) {
                        product.setStatus(BizConstants.Data_Status_Normal);
                        doctorProductMapper.updateByPrimaryKeySelective(product);
                    }
                }
            }
        } else { //新建
            InitDoctorProduct(doctorId, type);
        }
        return true;
    }

    @Override
    public Boolean updateDoctorServisTimes(Integer doctorId, Integer index, String values) {
        PlDoctorAvailableTime key = new PlDoctorAvailableTime();
        key.setDoctorId(doctorId);
        key.setTimeIndex(index);
        PlDoctorAvailableTime v = availableTimeMapper.selectByPrimaryKey(key);
        if(v!=null) {
            v.setTimeValue(values);
            availableTimeMapper.updateByPrimaryKeySelective(v);
        } else {
            key.setTimeValue(values);
            availableTimeMapper.insertSelective(key);
        }
        return true;
    }

    @Override
    public List<PlDoctorAvailableTime> getDoctorSercesTimes(Integer doctorId) {
        PlDoctorAvailableTimeExample ex = new PlDoctorAvailableTimeExample();
        ex.createCriteria().andDoctorIdEqualTo(doctorId);
        return availableTimeMapper.selectByExample(ex);
    }

    @Override
    public List<PlProduct> getDoctorSercesStatus(Integer doctorId) {
        PlProductExample ex = new PlProductExample();
        ex.createCriteria().andDoctorIdEqualTo(doctorId);
        return doctorProductMapper.selectByExample(ex);
    }

    @Override
    public List<PlOrder> getDoctorOrders(Integer doctorId, Integer type) {
        return customLogicMapper.getDoctorOrders(doctorId, type);
    }

    @Override
    public List<PatientVo> getNeedCheckedMyCase(Integer doctorId) {
        return customLogicMapper.getMyPatientVo(doctorId, null);
    }

    @Override
    public List<PlVip> getMyVips(Integer doctorId, Integer type) {
        PlVipExample ex = new PlVipExample();
        if(type.equals(BizConstants.VipStatus_ALL)) {
            ex.createCriteria().andDoctorIdEqualTo(doctorId);
        } else {
            ex.createCriteria().andDoctorIdEqualTo(doctorId).andStatusEqualTo(type);
        }
        return vipRecordMapper.selectByExample(ex);
    }

    @Override
    public Boolean acceptVipRequest(Integer doctorId, Integer vipId, Integer op) {
        PlVip v = vipRecordMapper.selectByPrimaryKey(vipId);
        if(op.equals(BizConstants.Op_Accept)) {
            v.setStatus(BizConstants.VipStatusActive);
            vipRecordMapper.updateByPrimaryKey(v);
            bizSrvs.updateVip(v.getUserId(), v.getDoctorId(), v.getProductId());
            //bedgeServices.UpdateUserBedge(v.getUserId(), BedgeServices.Type_User_My_Doctor, doctorId, 1);
            //pushServices.SendMessageToUserWithMp(v.getUserId(), "医生接受了您的私人医生服务");
            addDoctorVipBill(v);
        } else {
            v.setStatus(BizConstants.VipStatusReject);
            vipRecordMapper.updateByPrimaryKey(v);
            orderServices.cancelOrder(v.getOrderId());
            //pushServices.SendMessageToUserWithMp(v.getUserId(), "医生拒绝了您的私人医生服务");
        }
        return true;
    }

    private void addDoctorVipBill(PlVip vip) {
        PlDoctorBill bill = new PlDoctorBill();
        bill.setRefId(vip.getVipId());
        bill.setDoctorId(vip.getDoctorId());
        bill.setActiveTime(DateTool.DayOp(new Date(), 7));
        bill.setDes("私人医生");
        bill.setType(BizConstants.Bill_Type_Vip);
        PlOrder order = orderMapper.selectByPrimaryKey(vip.getOrderId());
        bill.setIncome(order.getOrderFee().doubleValue()/100.0);
        balanceServices.AddBill(bill);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean acceptCaseRequest(Integer doctorId, Integer caseId, Integer op) {
        PlCase c = caseMapper.selectByPrimaryKey(caseId);
        if(op.equals(BizConstants.Op_Accept)) {
            c.setStatus(BizConstants.CaseStats_Accept);
            caseMapper.updateByPrimaryKey(c);
            PlDockerUserRelation r = new PlDockerUserRelation();
            PlUser u = userMapper.selectByPrimaryKey(c.getUid());
            r.setDockerId(doctorId);
            r.setUnionid(u.getUnionid());
            r.setStatus(BizConstants.CaseStats_Accept);
            relationMapper.updateByPrimaryKeySelective(r);
            CaseReviewResultMsg msg = CaseReviewResultMsg.msgBuilder(u.getName(), u.getPhone(), "通过", "您的病例审核已通过");
            pushServices.SendMessageToUserWithMp(u.getUnionid(), JSON.toJSONString(msg));
            //pushServices.SendMessageToUserWithMp(u.getUnionid(), "患者关系已确认");
            bedgeServices.UpdateUserBedge(c.getUid(), BedgeServices.Type_User_Tab_Doctor, c.getDoctorId(), 1);
        } else {
            c.setStatus(BizConstants.CaseStats_Reject);
            caseMapper.updateByPrimaryKey(c);
            PlDockerUserRelation r = new PlDockerUserRelation();
            PlUser u = userMapper.selectByPrimaryKey(c.getUid());
            r.setDockerId(doctorId);
            r.setUnionid(u.getUnionid());
            r.setStatus(BizConstants.CaseStats_Reject);
            relationMapper.updateByPrimaryKeySelective(r);
            CaseReviewResultMsg msg = CaseReviewResultMsg.msgBuilder(u.getName(), u.getPhone(), "拒绝", "您的病例审核已被拒绝");
            pushServices.SendMessageToUserWithMp(u.getUnionid(),JSON.toJSONString(msg));
        }
        return true;
    }

    @Override
    public void updateAllDoctorStatics() {

    }

    private void InitDoctorProduct(Integer doctorId, Integer type) {
        Integer[] times= {10, 15, 20};
        Double[] prices = {168.00, 208.00, 228.00};
        PlProduct pro = new PlProduct();
        pro.setDoctorId(doctorId);
        pro.setType(type);
        switch (type.byteValue()) {
            case BizConstants.Consulting_Type_Msg:
                pro.setDes("图文咨询费");
                pro.setTime(3);
                pro.setPrice(16.8);
                pro.setUnitType("次");
                doctorProductMapper.insertSelective(pro);
                break;
            case BizConstants.Consulting_Type_Phone:
                pro.setDes("电话咨询费");
                for(int i=0;i<3;i++) {
                    pro.setUnitType(times[i].toString()+"分钟");
                    pro.setTime(times[i]);
                    pro.setPrice(prices[i]);
                    doctorProductMapper.insertSelective(pro);
                }
                break;
            case BizConstants.Consulting_Type_Video:
                pro.setDes("视频咨询费");
                for(int i=0;i<3;i++) {
                    pro.setUnitType(times[i].toString()+"分钟");
                    pro.setTime(times[i]);
                    pro.setPrice(prices[i]);
                    doctorProductMapper.insertSelective(pro);
                }
                break;
            case BizConstants.Product_Type_Week:
                pro.setDes("一周服务费");
                pro.setPrice(268.00);
                pro.setUnitType("周");
                pro.setTime(7);
                doctorProductMapper.insertSelective(pro);
                break;
            case BizConstants.Product_Type_Month:
                pro.setDes("一月服务费");
                pro.setPrice(648.00);
                pro.setUnitType("月");
                pro.setTime(30);
                doctorProductMapper.insertSelective(pro);
                break;
            case BizConstants.Product_Type_HalfYear:
                pro.setDes("半年服务费");
                pro.setPrice(1128.00);
                pro.setUnitType("半年");
                pro.setTime(180);
                doctorProductMapper.insertSelective(pro);
                break;
            case BizConstants.Product_Type_Year:
                pro.setDes("一年服务费");
                pro.setPrice(1928.00);
                pro.setUnitType("一年");
                pro.setTime(365);
                doctorProductMapper.insertSelective(pro);
                break;
                default:
                    break;
        }
    }

    private boolean checkVips(PlUserVip vip, PlProduct product) {
        switch (product.getType().byteValue()) {
            case BizConstants.Product_Type_Msg:
                return vip.getMsgTimesLeft()>0;
            case BizConstants.Product_Type_Phone:
                return vip.getPhoneTimesLeft()>0;
            case BizConstants.Product_Type_Video:
                return vip.getVideoTimesLeft()>0;
                default:
                    return false;
        }
    }

    private boolean updateVips(PlUserVip vip, PlProduct product) {
        switch (product.getType().byteValue()) {
            case BizConstants.Product_Type_Msg:
                vip.setMsgTimesLeft(vip.getMsgTimesLeft()-1);
                break;
            case BizConstants.Product_Type_Phone:
                vip.setPhoneTimesLeft(vip.getPhoneTimesLeft()-1);
                break;
            case BizConstants.Product_Type_Video:
                vip.setVideoTimesLeft(vip.getVideoTimesLeft()-1);
                break;
                default: return  false;
        }
        return userVipMapper.updateByPrimaryKeySelective(vip)>0;
    }
}
